package com.cn.ycy.config;

import com.cn.ycy.utils.SpringBeanUtils;
import com.google.common.base.Predicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Arrays;

@Configuration
@EnableSwagger2
//@ConditionalOnExpression(
//        "#{ (!'pro'.equalsIgnoreCase(environment['env']) || !'prod'.equalsIgnoreCase(environment['env']))  }"
//)
public class Swagger2Configuration {

  private static Logger LOGGER = LoggerFactory.getLogger(Swagger2Configuration.class);

  //接口名称
  @Value("${app.id}")
  private String appId;

  //接口扫描路径
  @Value("${swagger.multibasepackage:}")
  private String swaggerMultiBasePackage;

  //接口默认路径
  private static final String[] swaggerMultiBasePackageDefault = new String[]{"com.enn"};

  //接口联系人作者
  @Value("${swagger.cantact.name:}")
  private String swaggerContantName;

  //接口帮助url
  @Value("${swagger.cantact.url:}")
  private String swaggerContactUrl;

  //接口联系人email
  @Value("${swagger.cantact.email:}")
  private String swaggerContactEmail;

  //接口版本号
  @Value("${swagger.version:1.0.0}")
  private String swaggerContantVersion;

  @Autowired
  private ApplicationContext applicationContext;

  private static final String SEPARATOR = ",";

//	@Bean
	public Docket buildDocket() {
		return new Docket(DocumentationType.SWAGGER_2).apiInfo(buildApiInf()).select()
				.apis(RequestHandlerSelectors.basePackage("com")).paths(PathSelectors.any()).build();
	}

//  @Bean
//  public Docket buildDocket() {
//    String[] swaggerBasePackage = getbasePackagesByOrder();
//    LOGGER.info("swagger2 scanbasepackage {}", Arrays.toString(swaggerBasePackage));
//    return new Docket(DocumentationType.SWAGGER_2).apiInfo(buildApiInf()).select()
//            .apis(baseMultiPackage(swaggerBasePackage)).paths(PathSelectors.any()).build();
//  }

  private String[] getbasePackagesByOrder() {
    String[] swaggerBasePackage;
    String[] basePackagesFromSpringBootApplication;
    if (swaggerMultiBasePackage != null && swaggerMultiBasePackage.length() > 0) {
      //优先使用用户配置
      swaggerBasePackage = this.swaggerMultiBasePackage.split(SEPARATOR);
    } else if ((basePackagesFromSpringBootApplication = SpringBeanUtils.getBasePackagesFromSpringBootApplicationAnnotation(applicationContext)) != null) {
      //使用springboot启动类中指定的扫描路径
      swaggerBasePackage = basePackagesFromSpringBootApplication;
    } else {
      //使用默认路劲
      swaggerBasePackage = swaggerMultiBasePackageDefault;
    }
    return swaggerBasePackage;
  }

  private ApiInfo buildApiInf() {
    return new ApiInfoBuilder().title(appId + " API")
            .contact(new Contact(swaggerContantName, swaggerContactUrl, swaggerContactEmail))
            .version(swaggerContantVersion)
            .build();
  }


  /**
   * swagger 改写扫描方式，支持多路径扫描
   */
  private Predicate<RequestHandler> baseMultiPackage(final String[] multiBasePackages) {
    return new Predicate<RequestHandler>() {
      @Override
      public boolean apply(RequestHandler input) {
        String name = input.declaringClass().getPackage().getName();
        for (String basePackage : multiBasePackages) {
          if (basePackage != null && basePackage.length() > 0) {
            boolean isMatch = name.startsWith(basePackage);
            if (isMatch) return true;
          }
        }
        return false;
      }
    };
  }

}
